package com.jrelax.kit;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel.MapMode;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * MD5加密类
 *
 * @author ZENGCHAO
 */
public class Md5Kit {
    /**
     * MD5加密
     *
     * @param s
     * @return
     */
    public final static String encode(String s) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            byte[] btInput = s.getBytes("UTF-8");
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取文件的MD5值
     *
     * @param filePath
     * @return
     * @throws IOException
     */
    public static String file(String filePath) throws IOException {
        File file = new File(filePath);
        return file(file);
    }

    /**
     * 获取文件的MD5值
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static String file(File file) throws IOException {
        String md5 = null;
        int bufferSize = 256 * 1024;
        FileInputStream fis = null;
        DigestInputStream dis = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            fis = new FileInputStream(file);
            dis = new DigestInputStream(fis, md);
            byte[] buffer = new byte[bufferSize];
            while(dis.read(buffer) > 0);
            md = dis.getMessageDigest();
            byte[] resultByteArray = md.digest();
            md5 = byteArrayToHex(resultByteArray);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } finally {
            if(dis != null){
                dis.close();
            }
            if (fis != null) {
                fis.close();
            }
        }
//		if(file.exists()){
//			FileInputStream fis = null;
//			try {
//				fis = new FileInputStream(file);
//				MappedByteBuffer byteBuffer = fis.getChannel().map(MapMode.READ_ONLY, 0, file.length());
//				MessageDigest md = MessageDigest.getInstance("MD5");
//				md.update(byteBuffer);
//				BigInteger bi = new BigInteger(1, md.digest());
//				md5 = bi.toString(16);
//			} catch (FileNotFoundException e) {
//				e.printStackTrace();
//			} catch (NoSuchAlgorithmException e) {
//				e.printStackTrace();
//			} finally{
//				if(fis != null){
//					fis.close();
//				}
//			}
//		}else{
//			System.out.println("文件不存在！");
//		}
        return md5;
    }

    /***
     * 生成文件的MD5值，8位
     * @param filePath
     * @return
     * @throws IOException
     */
    public static String file_short_8(String filePath) throws IOException {
        String md5 = file(filePath);

        if (!StringKit.isBlank(md5) && md5.length() > 30) {
            return md5.substring(8, 16);
        }
        return null;
    }

    /***
     * 生成文件的MD5值，8位
     * @param file
     * @return
     * @throws IOException
     */
    public static String file_short_8(File file) throws IOException {
        String md5 = file(file);

        if (!StringKit.isBlank(md5) && md5.length() > 30) {
            return md5.substring(8, 16);
        }
        return null;
    }

    private static String byteArrayToHex(byte[] byteArray) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < byteArray.length; n++) {
            stmp = (Integer.toHexString(byteArray[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
            if (n < byteArray.length - 1) {
                hs = hs + "";
            }
        }
        return hs;
    }
}
